#include "common.h"

/*
 * sets b to be vec_ZZ of struct a, also changing its mag_sq value
 */
void setVec(vec *a, vec_ZZ &b)
{
  a->v = b;
  a->mag_sq = mag_sq(b);
}

/* 
 * returns magnitude squared of a
 */
ZZ mag_sq(vec_ZZ &a)
{
  ZZ sumsquares;
  for(int i = 0; i < a.length(); i++)
  {
    sumsquares+= sqr(a[i]);
  }
  return sumsquares;
}

/*
 * returns minimum(v - c * a) over integers c
 */
vec reduce(vec *v, vec *a)
{
  ZZ c; //minimize v - c * a
  ZZ dot; //dot product of v and a
  vec ret;

  //find c such that v - c* a is minimized
  InnerProduct(dot, v->v, a->v); //dot = inner product
  //c = round((t * x)/(x * x) ) where * is dot product
  RoundToZZ(c, MakeRR(dot, 0)/MakeRR(a->mag_sq,0));

  //set the values of ret.v and ret.mag_sq before returning
  ret.v = v->v - c * a->v;
  ret.mag_sq = v->mag_sq + c * c * a->mag_sq - 2 * c * dot;

  return ret;
}



